package com.atguigu.javaailangchain4j.tools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.javaailangchain4j.entity.Appointment;
import com.atguigu.javaailangchain4j.entity.Patient;
import com.atguigu.javaailangchain4j.entity.Schedule;
import com.atguigu.javaailangchain4j.service.AppointmentService;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class AppointmentTools {

    @Autowired
    private AppointmentService appointmentService;

    private Map<String, String> buildRequestBody(Map<String, String> additionalParams) {
        return new HashMap<>(additionalParams);
    }

    private JSONObject sendHttpRequest(String host,String path, Map<String, String> body) throws Exception {
//        String host = "http://localhost:8201";
        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        Map<String, String> query = new HashMap<>();


        HttpResponse response = com.atguigu.java.ai.langchain4j.utils.HttpUtils.doPost(
                host, path, method, headers, query, body);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        return JSONObject.parseObject(result);
    }

//    @Tool(name="预约挂号", value = "根据参数，先执行工具方法queryDepartment查询是否可预约，并直接给用户回答是否可预约，并让用户确认所有预约信息，用户确认后再进行预约。如果用户没有提供具体的医生姓名，请从向量存储中找到一位医生。")
    @Tool(name="预约挂号", value = "根据参数，先执行工具方法queryDepartment查询是否可预约，并直接给用户回答是否可预约，并让用户确认所有预约信息，用户确认后再进行预约。")
    public String bookAppointment(Appointment appointment,
                                  @P(value = "科室名称") String name,
                                  @P(value = "日期") String date
    ) throws Exception {
        System.out.println(" --------------------------执行了预约挂号-------------------------- ");

        //查找数据库中是否包含对应的预约记录
        Appointment appointmentDB = appointmentService.getOne(appointment);
        if(appointmentDB == null){
        	appointment.setId(null);//防止大模型幻觉设置了id
            if(appointmentService.save(appointment)){

                // 请求获取可预约的医生接口
                Map<String, String> body = buildRequestBody(Map.of("name", name, "date", date));
                JSONObject jsonObject = sendHttpRequest("http://localhost:8201","/api/hosp/select", body);
                Integer code = jsonObject.getInteger("code");
                // TODO 2025年11月12日16:35:29做到这里

                if(code == 200){
                    Schedule schedule = JSON.parseObject(jsonObject.getString("data"), Schedule.class);
                    // 获取到排号ID
                    String scheduleId = schedule.getId();
                    JSONObject submitOrder = sendHttpRequest("http://localhost:8207","/api/order/orderInfo/auth/submitOrder/"+scheduleId+"/7", new HashMap<>());
                    Integer submitOrderCode = submitOrder.getInteger("code");
                    if (submitOrderCode == 20000){
                        return "预约成功，并返回预约详情";
                    }
                } else {
                   return "该科室没有可预约的医生";
                }




            }else{
                return "预约失败";
            }
        }
        return "您在相同的科室和时间已有预约";
    }

    @Tool(name = "查询是否有号源", value="根据科室名称，日期，时间和医生查询是否有号源，并返回给用户")
    public boolean queryDepartment(
            @P(value = "科室名称") String name,
            @P(value = "日期") String date,
            @P(value = "时间，可选值：上午、下午") String time,
            @P(value = "医生名称", required = false) String doctorName
    ) {
        System.out.println(" --------------------------执行了查询号源-------------------------- ");
        System.out.println("查询是否有号源");
        System.out.println("科室名称：" + name);
        System.out.println("日期：" + date);
        System.out.println("时间：" + time);
        System.out.println("医生名称：" + doctorName);
        //TODO  根据memoryId给的信息 生成对应的用户姓名 身份证 性别 放入user表中



        //如果指定了医生名字，则判断医生是否有排班（没有排版返回false）

        try {
            //如果没有指定医生名字，则根据其他条件查询是否有可以预约的医生（有返回true，否则返回false）；
            Map<String, String> body = buildRequestBody(Map.of("name", name, "date", date));
            JSONObject jsonObject = sendHttpRequest("http://localhost:8201","/api/hosp/select", body);
            Integer code = jsonObject.getInteger("code");
            if(code == 200){
                return true;
            } else {
                //如果有排HttpUtils班，则判断医生排班时间段是否已约满（约满返回false，有空闲时间返回true）
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    @Tool(name="取消预约挂号", value = "根据参数，查询预约是否存在，如果存在则删除预约记录并返回取消预约成功，否则返回取消预约失败")
    public String cancelAppointment(Appointment appointment) throws Exception {
        System.out.println("取消预约");
        Appointment appointmentDB = appointmentService.getOne(appointment);
        if(appointmentDB != null){
            //删除预约记录
            if(appointmentService.removeById(appointmentDB.getId())){

                // 用户姓名
                String name = appointment.getUsername();

                JSONObject jsonObject = sendHttpRequest("http://localhost:8160","/api/user/patient/inner/getPatientOrderList/"+name, new HashMap<>());

                Integer code = jsonObject.getInteger("code");
                if(code == 20000){
                    JSONObject parseObject = JSON.parseObject(jsonObject.getString("data"));
                    Patient patient = JSON.parseObject(parseObject.getString("patient"), Patient.class);

                    // 获取到userId
                    Long userId = patient.getUserId();

                    // 根据用户ID取消订单 传给auth/cancelOrder/{userId}
                    JSONObject cancelOrderInfo = sendHttpRequest("http://localhost:8207","/api/order/orderInfo/auth/cancel/"+userId, new HashMap<>());
                    Integer cancelOrderInfoCode = cancelOrderInfo.getInteger("code");
                    if (cancelOrderInfoCode == 20000){
                        return "取消预约成功";
                    }else{
                        return "取消预约失败";
                    }

                } else {
                    return "取消预约失败";
                }

            }else{
                return "取消预约失败";
            }
        }
        //取消失败
        return "您没有预约记录，请核对预约科室和时间";
    }
}